package com.xunk.scene.handler.effectiveperiod;

import com.xunk.common.core.utils.SpringUtils;
import com.xunk.common.redis.service.RedisService;
import com.xunk.scene.domain.SceneConditionEffectivePeriod;
import com.xunk.scene.enums.RepeatTypeEnum;
import com.xunk.scene.handler.ConditionWrapper;
import com.xunk.scene.handler.DefaultConditionHandler;
import com.xunk.scene.handler.IConditionHandler;
import com.xunk.scene.util.ConditionUtil;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @ProjectName: HIM
 * @Package: com.xunk.scene.handler.effectiveperiod
 * @ClassName: ConditionEffectivePeriod
 * @Author: luanzhiwei
 * @Description: 生效时间段
 * @Date: 2021/5/12 15:15
 * @Version: 1.0
 */
@Slf4j
@NoArgsConstructor
public class EffectivePeriodLeaf extends DefaultConditionHandler implements IConditionHandler, ConditionWrapper {
    SceneConditionEffectivePeriod effectivePeriod;

    boolean flag = false;

    public EffectivePeriodLeaf(SceneConditionEffectivePeriod effectivePeriod) {
        this.effectivePeriod = effectivePeriod;
    }

    private RedisService redisService = SpringUtils.getBean(RedisService.class);

    /**
     * 判断条件是否满足
     *
     * @param oneMatchFlag true满足一条即可，false 需全部满足,生效时间段必须要满足，否则返回false
     * @return
     */
    @Override
    public boolean match(boolean oneMatchFlag) {
        try {
            String repeatType = effectivePeriod.getRepeatType();
            final String specificDay = effectivePeriod.getSpecificDay();
            switch (RepeatTypeEnum.getByCode(repeatType)) {
                case ALLDAY:
                case DAY:
                    flag = true;
                    break;
                case WORKDATE:
                    flag = ConditionUtil.isWeekday();
                    break;
                case WEEKEND:
                    flag = ConditionUtil.isWeekend();
                    break;
                case WEEK:
                    flag = ConditionUtil.isSpecificWeekly(specificDay);
                    break;
                default:
                    flag = false;
                    break;
            }
            String period = effectivePeriod.getEffectivePeriod();
            String[] split = period.split("-");
            final String start = split[0];
            final String end = split[1];
            if (!start.equals(end)) {
                //如果相同则认为全天生效，不判断真假，如果不相同则判断当前时间是否在配置时间内
                LocalTime time = LocalTime.now();
                flag = flag && time.isBefore(LocalTime.parse(end)) && time.isAfter(LocalTime.parse(start));
            }
        } catch (Exception e) {
            flag = false;
            log.info("生效时间段判断出现异常{}", e.getMessage());
        } finally {
            log.info("生效时间段条件id{}处理结果{}", effectivePeriod.getId(), flag);
            return flag;
        }
    }

    /**
     * 包装，将实体类封装为可操作的类型
     *
     * @param o
     * @return
     */
    @Override
    public <T> IConditionHandler wrap(T o) {
        return new EffectivePeriodLeaf((SceneConditionEffectivePeriod) o);
    }

    /**
     * 包装，将实体类封装为可操作的类型
     *
     * @param objects
     * @return
     */
    @Override
    public <T> List<IConditionHandler> wrap(List<T> objects) {
        Iterator<T> iterator = objects.iterator();
        List<IConditionHandler> list = new ArrayList<>();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            list.add(new EffectivePeriodLeaf((SceneConditionEffectivePeriod) next));
        }
        return list;
    }
}
